module fifo#(
    parameter WIDTH = 64,
    parameter DEPTH = 64
)(
    Reset,
    WrClk,
    WrEn,
    Data,
    RdClk,
    RdEn,
    Q,
    Empty,
    Full,
    Almost_Empty,
    Almost_Full
);
    input Reset;
    input WrClk;
    input RdClk;
    input WrEn;
    input RdEn;

    input  wire[WIDTH-1:0] Data;
    output reg [WIDTH-1:0] Q;
    output reg Empty;
    output reg Full;
    output reg Almost_Empty = 0;
    output reg Almost_Full = 0;
    reg [WIDTH-1:0] mem[DEPTH-1:0];

    reg[7:0] rd_ptr = 0;
    reg[7:0] wr_ptr = 0;

    always @(posedge RdClk) begin
        if(wr_ptr!=rd_ptr)
            Empty <= 0;
        else
            Empty <= 1;
        if(RdEn)begin
            if(rd_ptr<wr_ptr)begin
                Q <= mem[rd_ptr];
                rd_ptr <= rd_ptr + 1;
            end
            else if(rd_ptr>wr_ptr)begin
                Q <= mem[rd_ptr];
                if(rd_ptr>=DEPTH)
                    rd_ptr <= 0;
                else
                    rd_ptr <= rd_ptr + 1;
            end
            else begin
                //Q       <= 0;
            end
        end
    end

    always @(posedge WrClk) begin
        if(wr_ptr+1==rd_ptr)
            Full <= 1;
        else
            Full <= 0;

        if(WrEn)begin
            if(wr_ptr<DEPTH)begin
                if(wr_ptr>=rd_ptr)begin
                    //没有溢出
                    mem[wr_ptr] <= Data;
                    wr_ptr <= wr_ptr + 1;
                end
                else if(wr_ptr+1==rd_ptr) begin
                    //已经满了
                end
            end
            else begin
                //重启
                if(rd_ptr>0)begin
                    wr_ptr <= 1;
                    mem[0] <= Data;
                end
            end
        end
    end

endmodule